package com.yuyi.config;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConfiguration {
    
  /**
   * 配置shiro拦截器
   * @param securityManager
   * @return
   */
  @Bean
  public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(securityManager);
    Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
    filterChainDefinitionMap.put("/kefuloging", "anon");
    filterChainDefinitionMap.put("/kefulogout", "anon");
//    filterChainDefinitionMap.put("/**","authc");   
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    return shiroFilterFactoryBean;
  }
  
  /**
   * 配置shiro认证授权
   * @return
   */
  @Bean
  public MyShiroRealm myShiroRealm() {
    MyShiroRealm myShiroRealm = new MyShiroRealm();
    return myShiroRealm;
  }
  
  /**
   * 配置加密方式
   * @return
   */
  @Bean
  public HashedCredentialsMatcher hashedCredentialsMatcher() {
    HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    hashedCredentialsMatcher.setHashAlgorithmName("md5");
    hashedCredentialsMatcher.setHashIterations(2);
    return hashedCredentialsMatcher;
  }
  
  /**
   * 配置核心安全事务管理器
   * @return
   */
  @Bean(name="securityManager")
  public SecurityManager securityManager() {
      DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
      //设置自定义realm.
      securityManager.setRealm(myShiroRealm());
      return securityManager;
  }

  
  /**
   * 配置sessionDAO
   * SessionDAO的作用是为Session提供CRUD并进行持久化的一个shiro组件
   * MemorySessionDAO 直接在内存中进行会话维护
   * EnterpriseCacheSessionDAO  提供了缓存功能的会话维护，默认情况下使用MapCache实现，内部使用ConcurrentHashMap保存缓存的会话。
   * @return
   */
  @Bean
  public SessionDAO sessionDAO() {
      MemorySessionDAO memorySessionDAO = new MemorySessionDAO();
      return memorySessionDAO;
  }
  
  /**
   * 管理shiro一些bean的生命周期
   * @return
   */
  @Bean(name = "lifecycleBeanPostProcessor")
  public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }
  
  /**
   * DefaultAdvisorAutoProxyCreator是用来扫描上下文，
   * 寻找所有的Advistor(通知器），将这些Advisor应用到所有符合切入点的Bean中。
   * 所以必须在lifecycleBeanPostProcessor创建之后创建，
   * 所以用了depends-on=”lifecycleBeanPostProcessor”> 
   * @return
   */
  @Bean
  public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
    defaultAAP.setProxyTargetClass(true);
    return defaultAAP;
  }
  
  /**
   *  开启shiro aop注解支持.
   *  使用代理方式;所以需要开启代码支持;
   * @param securityManager
   * @return
   */
  @Bean
  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
    authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
    return authorizationAttributeSourceAdvisor;
  }
  
  
}
